package com.rfsp.common.controller;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.rfsp.common.pojo.bo.Result;
import com.rfsp.common.shiro.ShiroUtils;
import com.rfsp.common.util.FileUtil;
import com.rfsp.common.util.StringUtil;
import com.rfsp.common.enums.SystemConst;
import com.rfsp.common.pojo.vo.UserVO;

@Controller
@RequestMapping("/uploader")
public class UploadController {
	/**上传地址*/
    @Value("${mcp.file-upload-path}")
    private String filePath;
    
    @Value("${mcp.file-temp-path}")
    private String mcpTempPath;

    // 跳转上传页面
    @RequestMapping("/form")
    public String form(HttpServletRequest request, Model model) {
    	model.addAttribute("ext", request.getParameter("ext"));
    	model.addAttribute("fileSizeTotalMbLimit", "10");
    	model.addAttribute("fileSizeMbLimit", "10");
    	//根据键值获得上传缓存
		String attachFilePathsKey = request.getParameter("attachFilePathsKey");
		String key=attachFilePathsKey;
		String uploadContent=getUploadContentByKey(key);
		model.addAttribute("uploadContent", uploadContent);
        return "/base/uploader/form";
    }

    // 执行上传
    @RequestMapping("/upload")
    public String upload(MultipartHttpServletRequest request, Model model) {
//        // 获取上传文件名        
//        String filename = file.getOriginalFilename();
//        // 定义上传文件保存路径
//        String path = filePath+"/";
//        // 新建文件
//        File filepath = new File(path, filename);
//        // 判断路径是否存在，如果不存在就创建一个
//        if (!filepath.getParentFile().exists()) {
//            filepath.getParentFile().mkdirs();
//        }
//        try {
//            // 写入文件
//            file.transferTo(new File(path + File.separator + filename));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        // 将src路径发送至html页面
//        model.addAttribute("filename", path + File.separator + filename);
        

        model.addAttribute("event","success");
        model.addAttribute("tips","");
		
		MultipartHttpServletRequest multipartRequest =  request;
//		List<MultipartFile> fileList = multipartRequest.getFiles("file");
		//List<MultipartFile> fileList = (List<MultipartFile>) multipartRequest.getAttribute("fileList");
		List<MultipartFile> fileList = multipartRequest.getFiles("fileList");
		
		Integer fileSizeMbLimit=10;
		if(request.getParameter("fileSizeMbLimit")!=null){
			fileSizeMbLimit=Integer.valueOf(request.getParameter("fileSizeMbLimit"));
		};
		
		String type = request.getParameter("type");
		UserVO user=null;
		
		
		Result childResult;
		List<Result> childResultList=new ArrayList<Result>();
		
		if(!(null==ShiroUtils.getUserVO())) {
        	user = ShiroUtils.getUserVO();
        }
		
		for(MultipartFile file:fileList){
			childResult=upload(file,user,type,fileSizeMbLimit);
			childResultList.add(childResult);
		}

		Result result=new Result();
		result.setEvent(Result.EVENT_SUCCESS);
		
		String itemTemplate="{event:\"{event}\",tips:\"{tips}\",fileName:\"{fileName}\",fileSize:{fileSize},serverFileName:\"{serverFileName}\"}";
		
		String temp="";
		
		String event;
		String tips = "";
		String fileName;
		String fileSize;
		String serverFileName;
		
		Integer failCount=0;
		
		StringBuffer sb=new StringBuffer();
		
		for(Result item:childResultList){
			event=item.getEvent();
			tips=item.getTips();
			fileName=item.getData().get("fileName").toString();
			fileSize=item.getData().get("fileSize").toString();
			serverFileName=item.getData().get("serverFileName").toString();
			
			temp=itemTemplate;
			temp=temp.replace("{event}", event);
			temp=temp.replace("{tips}", tips);
			temp=temp.replace("{fileName}", fileName);
			temp=temp.replace("{fileSize}", fileSize);
			temp=temp.replace("{serverFileName}", serverFileName);
			
			sb.append(",");
			sb.append(temp);
			
			if(Result.EVENT_FAIL.equals(item.getEvent())){
				failCount++;
			}
		}
		
		if(sb.length()>0){
			sb.deleteCharAt(0);
		}
//		tips="";
		model.addAttribute("event", Result.EVENT_SUCCESS);
		
		if(failCount>0){
			tips="有 "+failCount+" 个文件上传不成功，请检查结果";
			model.addAttribute("event", Result.EVENT_FAIL);
		}
			
		
		model.addAttribute("tips", tips);
		
		model.addAttribute("fileList",sb.toString());  
        return "/base/uploader/upload";
    }
    
	/**
	 * 根据键值获得上传缓存
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String getUploadContentByKey(String key){
		StringBuffer sb=new StringBuffer();
		String upload_path_temp = "/mcpTemp/";//临时路径
		
		String itemTemplate="{'event':'{event}','tips':'{tips}','fileName':'{fileName}','fileSize':{fileSize},'serverFileName':'{serverFileName}'}";
		String temp="";
		
		// 多个附件文件
		String attachFilePathsKey = key;
		if(null!=attachFilePathsKey&&!"".equals(attachFilePathsKey)){
			
			List<Map<String,String>> keyValueList = (List<Map<String,String>>)ShiroUtils.get(attachFilePathsKey);
			ShiroUtils.removeSession(attachFilePathsKey);
			
			String event="success";
			String tips="上传完成";
			String serverFileName;
			String fileName;
			File file;
			Long fileSize;
			
			if(null!=keyValueList && keyValueList.size()>0){
				for(Map<String,String> item:keyValueList){
					serverFileName=item.get("inifileName");
					fileName=item.get("fileName");
					file = new File(upload_path_temp+serverFileName);
					fileSize=file.length();
					
					temp=itemTemplate;
					temp=temp.replace("{event}", event);
					temp=temp.replace("{tips}", tips);
					temp=temp.replace("{fileName}", fileName);
					temp=temp.replace("{fileSize}", fileSize.toString());
					temp=temp.replace("{serverFileName}", serverFileName);
					
					sb.append(",");
					sb.append(temp);
				}
			}
		}
		if(sb.length()>0){
			sb.deleteCharAt(0);
		}
		return sb.toString();
	}
	
	/**
	 * 上传文件
	 * @param file
	 * @param user
	 * @param type
	 * @return
	 */
	public Result upload(MultipartFile file,UserVO user,String types,Integer fileSizeMbLimit) {
		String fileName;
		Long fileSize;
		String ext;
		
		fileName=file.getOriginalFilename();
		fileSize=file.getSize();
		
		ext = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
		
		Result result=new Result();
		result.setEvent(Result.EVENT_SUCCESS);
		result.setTips("上传成功");
		result.getData().put("fileName", fileName);
		result.getData().put("fileSize", fileSize);
		result.getData().put("serverFileName", "");
		
		if (types.equals("creditor_normal_xls")) {
			if (!(".xls".equals(ext))) {
				result.setEvent(Result.EVENT_FAIL);
				result.setTips("请上传.xls格式的附件！");
				return result;
			}
		} else {
			//页面允许的扩展名验证
			if(types!=null && !"".equals(types)){
				Result extResult=validateExt(ext,types);
				if(extResult.getEvent().equals(Result.EVENT_FAIL)){
					result.setEvent(Result.EVENT_FAIL);
					result.setTips(extResult.getTips());
					return result;
				}
			}
			//系统允许的扩展名验证
			if (!SystemConst.ATTACH_TYPE.contains(ext)) {
				result.setEvent(Result.EVENT_FAIL);
				result.setTips("请上传jpg、jpeg、png、pdf、rar、zip、xls格式的附件！");
				return result;
			}
		}
		
		if (fileName.substring(0, fileName.lastIndexOf(".")).length() > 60) {
			result.setEvent(Result.EVENT_FAIL);
			result.setTips("附件名字最多60个字符！");
			return result;
		}
		if (fileSize> 1024*1024*fileSizeMbLimit) {
			result.setEvent(Result.EVENT_FAIL);
			result.setTips("上传失败！上传附件大小超过 "+fileSizeMbLimit+" MB！");
			return result;
		}
		
		if (Result.EVENT_SUCCESS.equals(result.getEvent())) {
			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
			Date d = new Date();
			String save_name = "";
			if (null == user) {
				save_name = df.format(d) + "_" + new Random().nextInt(1000000) + "_" + "regUserName" + ext;
			} else {
				save_name = df.format(d) + "_" + new Random().nextInt(1000000) + "_" + user.getUserName() + ext;
			}
			String tempPath = FileUtil.getRootPath(mcpTempPath);
			String dateStr = StringUtil.dateToString(new Date(), "yyyy/MM/dd");// 子目录年月路径
			
			File dir = new File(tempPath + dateStr);
			if (!dir.exists() || !dir.isDirectory()){
				dir.mkdirs();// 目录不存在 创建
			}
			FileOutputStream outputStream = null;
			try {
				outputStream = new FileOutputStream(new File(tempPath+ dateStr + "/" + save_name));
				outputStream.write(file.getBytes());
				outputStream.close();
				outputStream=null;
				
				result.setEvent(Result.EVENT_SUCCESS);
				result.setTips("上传成功");
				String ServerFileName=dateStr + "/" + save_name;
				result.getData().put("serverFileName", ServerFileName);
				return result;
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				
				result.setEvent(Result.EVENT_FAIL);
				result.setTips("上传失败");
				return result;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				
				result.setEvent(Result.EVENT_FAIL);
				result.setTips("上传失败");
				return result;
			}finally {
				if (outputStream != null) {
					try {
						outputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		result.setEvent(Result.EVENT_FAIL);
		result.setTips("未知错误");
		return result;
	}
    
	/**
	 * 验证文件扩展名
	 * @param ext
	 * @param types
	 * @return
	 */
	private Result validateExt(String ext,String allowExts){
		ext=ext.toLowerCase();
		allowExts=allowExts.toLowerCase();
		String[] allowExtArray=allowExts.split(";");
		StringBuffer sb=new StringBuffer();
		ext=ext.replace(".","");
		
		for(int i=0;i<allowExtArray.length;i++){
			allowExtArray[i]=allowExtArray[i].replace("*.", "");
			sb.append("、");
			sb.append(allowExtArray[i]);
		}
		if(sb.length()>0){
			sb.deleteCharAt(0);
		}
		
		Result result=new Result();
		result.setEvent(Result.EVENT_FAIL);
		result.setTips("请上传"+sb.toString()+"格式的附件！");
		
		for(int i=0;i<allowExtArray.length;i++){
			if(ext.equals(allowExtArray[i])){
				result.setEvent(Result.EVENT_SUCCESS);
				result.setTips("");
				break;
			}
		}
		return result;
	}
    
}
